﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using log4net;

namespace Helpers
{
    /// <summary>
    /// 提供一组日志的方法
    /// 日志记录方法可以使用第三方组件,如log4net
    /// </summary>
    public class Logger
    {
        /// <summary>
        /// log4net配置文件路径
        /// </summary>
        static string _logConfig = System.Web.HttpContext.Current.Server.MapPath("log4net.config");

        static Logger()
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(_logConfig));
        }

        /// <summary>
        /// 写日志方法
        /// </summary>
        /// <param name="message"></param>
        /// <param name="fileName"></param>
        private static void InputLogger(string message, string fileName)
        {
            var urlCollection = System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values;
            string mvcUrl = System.Web.HttpContext.Current.Server.MapPath("/Logger/"
                    + urlCollection["controller"].ToString()
                    + "/"
                    + urlCollection["action"].ToString()
                    + "/");
            string filePath = mvcUrl + fileName;
            if (ConfigurationManager.AppSettings["isLog4net"] == null
                || ConfigurationManager.AppSettings["isLog4net"] == "false")
            {
                string dir = filePath.Substring(0, filePath.LastIndexOf("\\"));
                if (!System.IO.Directory.Exists(dir))
                {
                    System.IO.Directory.CreateDirectory(dir);
                }
                using (System.IO.StreamWriter srFile = new System.IO.StreamWriter(filePath, true))
                {
                    srFile.WriteLine(message);
                    srFile.Close();
                    srFile.Dispose();
                }
            }
            else
            {
                var iLog = log4net.LogManager.GetLogger("tsingda.Logger");
                ChangeLog4netLogFileName(iLog, filePath, message);

            }
        }

        private static void ChangeLog4netLogFileName(log4net.ILog iLog, string filePath, string message)
        {
            log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
            if (logImpl != null)
            {
                var ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
                var rfa = ac[0] as log4net.Appender.RollingFileAppender;
                if (rfa != null)
                {
                    string dir = filePath.Substring(0, filePath.LastIndexOf("\\"));
                    if (!System.IO.Directory.Exists(dir))
                    {
                        System.IO.Directory.CreateDirectory(dir);
                    }
                    rfa.File = filePath;
                    // 更新Writer属性
                    rfa.Writer = new System.IO.StreamWriter(rfa.File, rfa.AppendToFile, rfa.Encoding);
                    rfa.Writer.WriteLine(message);
                    rfa.Writer.Close();
                    rfa.Writer.Dispose();
                    rfa.Close();

                }

            }
        }

        /// <summary>
        /// 记录代码运行时间
        /// </summary>
        public static void Logger_Timer(string message, Action action, string fileName)
        {
            StringBuilder str = new StringBuilder();
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            str.Append(message);
            action();
            str.Append("代码段运行时间:" + sw.ElapsedMilliseconds + "毫秒");
            InputLogger(str.ToString(), fileName);
            sw.Stop();
        }

        /// <summary>
        /// 记录代码运行异常
        /// </summary>
        public static void Logger_Exception(string message, Action action, string fileName)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                InputLogger("代码段出现异常,信息为" + ex.Message, fileName);
            }
        }
    }
}